<?php

use Web3\Utils;
use Vier\EthTool\Credential;
use Vier\EthTool\TokenBase;
use Vier\EthTool\Callback;

/**
 *
 */
class Token20 extends TokenBase{

	function __construct($conf=NULL){
		parent::__construct($conf);
        $this->monitor = [
            'Approval'=>[],
            'Paused'=>[],
            'Transfer'=>[],
            'Unpaused'=>[],
        ];
	}

    // ---------------------- 事件 ----------------------

    /**
     * @method onApproval
     * @param $callback ($owner,$spender,$value)=>{}
     */
    public function onApproval($callback){
        $this->onEvent('Approval',function($e,$owner,$spender,$value)use($callback){
                $value = Utils::toBn($value)->toString();
                call_user_func($callback,$e,$owner,$spender,$value);
            });
    }

    /**
     * @method onPaused
     * @param $callback ($account)=>{}
     */
    public function onPaused($callback){
        $this->onEvent('Paused',function($e,$account)use($callback){
                call_user_func($callback,$e,$account);
            });
    }

    /**
     * @method onTransfer 监听交易事件
     * @param $callback ($from,$to,$value)=>{}
     */
    public function onTransfer($callback){
        $this->onEvent('Transfer',function($e,$from,$to,$value)use($callback){
                $value = Utils::toBn($value)->toString();
                call_user_func($callback,$e,$from,$to,$value);
            });
    }

    /**
     * @method onUnpaused
     * @param $callback ($account)=>{}
     */
    public function onUnpaused($callback){
        $this->onEvent('Unpaused',function($e,$account)use($callback){
                call_user_func($callback,$e,$account);
            });
    }

    // ---------------------- 信息查询 ----------------------

    public function balanceOf($account){
        $cb = new Callback;
        $opts = [];
        $this->contract->call('balanceOf',$account,$opts,$cb);
        return Utils::toBn($cb->result[0])->toString();
    }

    // ---------------------- 合约操作 ----------------------

    public function burn($account,$amount,$unit='wei'){
        $unit=='wei' or $amount=Utils::toWei($amount,$unit)->toString();
        $this->setOperator($this->managerKey);
        return $this->send('burn',$account,$amount);
    }

    public function mint($account,$amount,$unit='wei'){
        $unit=='wei' or $amount=Utils::toWei($amount,$unit)->toString();
        $this->setOperator($this->managerKey);
        return $this->send('mint',$account,$amount);
    }

    public function transfer($recipient,$amount,$unit='wei'){
        $unit=='wei' or $amount=Utils::toWei($amount,$unit)->toString();
        $this->setOperator($this->managerKey);
        return $this->send('transfer',$recipient,$amount);
    }

    public function approve($userKey,$amount,$unit='wei'){
        $unit=='wei' or $amount=Utils::toWei($amount,$unit)->toString();
        $oCredential = Credential::fromKey($this->managerKey);

        $this->setOperator($userKey);
        return $this->send('approve',$oCredential->getAddress(),$amount);
    }

    public function transferFrom($from,$to,$amount,$unit='wei'){
        $unit=='wei' or $amount=Utils::toWei($amount,$unit)->toString();
        $this->setOperator($this->managerKey);
        $to==null && $to = $this->credential->getAddress();
        return $this->send('transferFrom',$from,$to,$amount);
    }

    public function trans2own($userKey,$amount,$unit='wei'){
        $unit=='wei' or $amount=Utils::toWei($amount,$unit)->toString();
        $this->approve($userKey,$amount);
        return $this->transferFrom(Credential::fromKey($userKey)->getAddress(),null,$amount);
    }

}